package com.lxmes.sales.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.lxmes.base.domain.NcTechDetail;
import com.lxmes.base.mapper.NcTechDetailMapper;
import com.lxmes.common.utils.DateUtils;
import com.lxmes.common.utils.NewNumber;
import com.lxmes.common.utils.SecurityUtils;
import com.lxmes.common.utils.bean.BeanUtils;
import com.lxmes.sales.domain.*;
import com.lxmes.sales.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lxmes.common.utils.StringUtils;
import com.lxmes.common.utils.bean.BeanValidators;
import com.lxmes.common.exception.ServiceException;

import javax.annotation.Resource;
import javax.print.DocFlavor;
import javax.validation.Validator;

import com.lxmes.sales.service.INcProductPreSchedulingPlanMainService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 产品预排产计划总Service业务层处理
 *
 * @author lx
 * @date 2023-04-17
 */
@Service
public class NcProductPreSchedulingPlanMainServiceImpl implements INcProductPreSchedulingPlanMainService
{
    @Resource
    private NcProductPreSchedulingPlanMainMapper ncProductPreSchedulingPlanMainMapper;

    @Resource
    private NcProductPreSchedulingPlanMapper ncProductPreSchedulingPlanMapper;//成品

    @Resource
    private NcPackagingPreSchedulingPlanMapper ncPackagingPreSchedulingPlanMapper;//总成

    @Resource
    private NcAssemblyPreSchedulingPlanMapper ncAssemblyPreSchedulingPlanMapper;//部装

    @Resource
    private NcProcessingPreSchedulingPlanMapper ncProcessingPreSchedulingPlanMapper;//零件

    @Resource
    private NcTechDetailMapper ncTechDetailMapper;



    @Autowired
    protected Validator validator;
    /**
     * 查询产品预排产计划总
     *
     * @param id 产品预排产计划总主键
     * @return 产品预排产计划总
     */
    @Override
    public NcProductPreSchedulingPlanMain selectNcProductPreSchedulingPlanMainById(Long id)
    {
        return ncProductPreSchedulingPlanMainMapper.selectNcProductPreSchedulingPlanMainById(id);
    }

    /**
     * 查询产品预排产计划总列表
     *
     * @param ncProductPreSchedulingPlanMain 产品预排产计划总
     * @return 产品预排产计划总
     */
    @Override
    public List<NcProductPreSchedulingPlanMain> selectNcProductPreSchedulingPlanMainList(NcProductPreSchedulingPlanMain ncProductPreSchedulingPlanMain)
    {
        return ncProductPreSchedulingPlanMainMapper.selectNcProductPreSchedulingPlanMainList(ncProductPreSchedulingPlanMain);
    }

    /**
     * 新增产品预排产计划总
     *
     * @param ncProductPreSchedulingPlanMain 产品预排产计划总
     * @return 结果
     */
    @Override
    public int insertNcProductPreSchedulingPlanMain(NcProductPreSchedulingPlanMain ncProductPreSchedulingPlanMain)
    {
        return ncProductPreSchedulingPlanMainMapper.insertNcProductPreSchedulingPlanMain(ncProductPreSchedulingPlanMain);
    }

    /**
     * 修改产品预排产计划总
     *
     * @param ncProductPreSchedulingPlanMain 产品预排产计划总
     * @return 结果
     */
    @Override
    public int updateNcProductPreSchedulingPlanMain(NcProductPreSchedulingPlanMain ncProductPreSchedulingPlanMain)
    {
        return ncProductPreSchedulingPlanMainMapper.updateNcProductPreSchedulingPlanMain(ncProductPreSchedulingPlanMain);
    }

    /**
     * 批量删除产品预排产计划总
     *
     * @param ids 需要删除的产品预排产计划总主键
     * @return 结果
     */
    @Override
    public int deleteNcProductPreSchedulingPlanMainByIds(Long[] ids)
    {
        return ncProductPreSchedulingPlanMainMapper.deleteNcProductPreSchedulingPlanMainByIds(ids);
    }

    /**
     * 删除产品预排产计划总信息
     *
     * @param id 产品预排产计划总主键
     * @return 结果
     */
    @Override
    public int deleteNcProductPreSchedulingPlanMainById(Long id)
    {
        return ncProductPreSchedulingPlanMainMapper.deleteNcProductPreSchedulingPlanMainById(id);
    }
    @Override
    public String imporIteminfo(List<NcProductPreSchedulingPlanMain> ncProductPreSchedulingPlanMainList, boolean updateSupport, String operName) {
        if (StringUtils.isNull(ncProductPreSchedulingPlanMainList) || ncProductPreSchedulingPlanMainList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (NcProductPreSchedulingPlanMain ncProductPreSchedulingPlanMain : ncProductPreSchedulingPlanMainList)
        {
            try
            {
                BeanValidators.validateWithException(validator, ncProductPreSchedulingPlanMain);
                ncProductPreSchedulingPlanMain.setCreateBy(operName);
                ncProductPreSchedulingPlanMain.setCreateTime(new Date());
                ncProductPreSchedulingPlanMain.setUpdateBy(operName);
                ncProductPreSchedulingPlanMain.setPreProductionNumber("YP"+ NewNumber.createNewNumber(ncProductPreSchedulingPlanMainMapper.getPcMainCode(DateUtils.getDate())));
                this.insertNcProductPreSchedulingPlanMain(ncProductPreSchedulingPlanMain);
                successNum++;
                successMsg.append("<br/>" + successNum + "数据导入成功");
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/> 数据导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    @Transactional
    public int auditProduct(Long[] ids) {
        for(long id : ids){
            NcProductPreSchedulingPlanMain ncProductPreSchedulingPlanMain = ncProductPreSchedulingPlanMainMapper.selectNcProductPreSchedulingPlanMainById(id);
            String isAudit = ncProductPreSchedulingPlanMain.getIsAudit();
            if("1".equals(isAudit)){
                throw new RuntimeException(ncProductPreSchedulingPlanMain.getProductName()+"已经审核,不能再审！");
            }

            NcTechDetail ncTechDetail = new NcTechDetail();
            ncTechDetail.setCpbm(ncProductPreSchedulingPlanMain.getProductNumber());
            List<NcTechDetail> ncTechDetails = ncTechDetailMapper.selectNcTechDetailList(ncTechDetail);
            if(ncTechDetails.size()>0){
                Map<String, List<NcTechDetail>> lineTypeGroup = ncTechDetails.stream().collect(Collectors.groupingBy(NcTechDetail::getLineType));
                lineTypeGroup.forEach((k, v) -> {
                    if("1.0".equals(k)){
                        String ppn = NewNumber.createNewNumber(ncProductPreSchedulingPlanMapper.getPcMainCode(DateUtils.getDate()));
                        int index = ppn.length() - 3;
                        String newStr = ppn.substring(0, index) + "1" + ppn.substring(index + 1);
                        for(NcTechDetail techDetail : v){
                            NcProductPreSchedulingPlan ncProductPreSchedulingPlan = new NcProductPreSchedulingPlan();
                            BeanUtils.copyProperties(ncProductPreSchedulingPlanMain,ncProductPreSchedulingPlan);
                            ncProductPreSchedulingPlan.setPreProductionNumber("YP"+ newStr);
                            ncProductPreSchedulingPlan.setGwCode(techDetail.getGwCode());
                            ncProductPreSchedulingPlan.setGwName(techDetail.getGwName());
                            ncProductPreSchedulingPlan.setGwItemCode(techDetail.getItemCode());
                            ncProductPreSchedulingPlan.setGwItemName(techDetail.getItemName());
                            ncProductPreSchedulingPlan.setUnit(techDetail.getUnit());
                            ncProductPreSchedulingPlan.setDtyl(Double.parseDouble(techDetail.getDtyl()));
                            ncProductPreSchedulingPlan.setDdyl(Double.parseDouble(techDetail.getDtyl())*ncProductPreSchedulingPlanMain.getOrderNum());
                            ncProductPreSchedulingPlan.setCreateBy(SecurityUtils.getUsername());
                            ncProductPreSchedulingPlan.setCreateTime(new Date());
                            ncProductPreSchedulingPlanMapper.insertNcProductPreSchedulingPlan(ncProductPreSchedulingPlan);
                        }

                    }else if("2.0".equals(k)){
                        String ppn = NewNumber.createNewNumber(ncPackagingPreSchedulingPlanMapper.getPcMainCode(DateUtils.getDate()));
                        int index = ppn.length() - 3;
                        String newStr = ppn.substring(0, index) + "2" + ppn.substring(index + 1);
                        for(NcTechDetail techDetail : v){
                            NcPackagingPreSchedulingPlan ncPackagingPreSchedulingPlan = new NcPackagingPreSchedulingPlan();
                            BeanUtils.copyProperties(ncProductPreSchedulingPlanMain,ncPackagingPreSchedulingPlan);
                            ncPackagingPreSchedulingPlan.setPreProductionNumber("YP"+ newStr);
                            ncPackagingPreSchedulingPlan.setGwCode(techDetail.getGwCode());
                            ncPackagingPreSchedulingPlan.setGwName(techDetail.getGwName());
                            ncPackagingPreSchedulingPlan.setGwItemCode(techDetail.getItemCode());
                            ncPackagingPreSchedulingPlan.setGwItemName(techDetail.getItemName());
                            ncPackagingPreSchedulingPlan.setUnit(techDetail.getUnit());
                            ncPackagingPreSchedulingPlan.setDtyl(Double.parseDouble(techDetail.getDtyl()));
                            ncPackagingPreSchedulingPlan.setDdyl(Double.parseDouble(techDetail.getDtyl())*ncProductPreSchedulingPlanMain.getOrderNum());
                            ncPackagingPreSchedulingPlan.setCreateBy(SecurityUtils.getUsername());
                            ncPackagingPreSchedulingPlan.setCreateTime(new Date());
                            ncPackagingPreSchedulingPlan.setZcCode(techDetail.getLineItemCode());
                            ncPackagingPreSchedulingPlan.setAssemblyName(techDetail.getLineItemName());
                            ncPackagingPreSchedulingPlanMapper.insertNcPackagingPreSchedulingPlan(ncPackagingPreSchedulingPlan);
                        }

                    }else if("3.0".equals(k)){
                        String ppn = NewNumber.createNewNumber(ncAssemblyPreSchedulingPlanMapper.getPcMainCode(DateUtils.getDate()));
                        int index = ppn.length() - 3;
                        String newStr = ppn.substring(0, index) + "3" + ppn.substring(index + 1);
                        for(NcTechDetail techDetail : v){
                            NcAssemblyPreSchedulingPlan ncAssemblyPreSchedulingPlan = new NcAssemblyPreSchedulingPlan();
                            BeanUtils.copyProperties(ncProductPreSchedulingPlanMain,ncAssemblyPreSchedulingPlan);
                            ncAssemblyPreSchedulingPlan.setPreProductionNumber("YP"+ newStr);
                            ncAssemblyPreSchedulingPlan.setGwCode(techDetail.getGwCode());
                            ncAssemblyPreSchedulingPlan.setGwName(techDetail.getGwName());
                            ncAssemblyPreSchedulingPlan.setGwItemCode(techDetail.getItemCode());
                            ncAssemblyPreSchedulingPlan.setGwItemName(techDetail.getItemName());
                            ncAssemblyPreSchedulingPlan.setUnit(techDetail.getUnit());
                            ncAssemblyPreSchedulingPlan.setDtyl(techDetail.getDtyl());
                            ncAssemblyPreSchedulingPlan.setDdyl(Double.parseDouble(techDetail.getDtyl())*ncProductPreSchedulingPlanMain.getOrderNum()+"");
                            ncAssemblyPreSchedulingPlan.setCreateBy(SecurityUtils.getUsername());
                            ncAssemblyPreSchedulingPlan.setCreateTime(new Date());
                            ncAssemblyPreSchedulingPlan.setPartNumber(techDetail.getLineItemCode());
                            ncAssemblyPreSchedulingPlan.setPartName(techDetail.getLineItemName());
                            NcTechDetail techDetails = selectItem(techDetail.getLineItemCode(), techDetail.getCpbm());
                            if(StringUtils.isNotNull(techDetails)){
                                ncAssemblyPreSchedulingPlan.setZcCode(techDetails.getLineItemCode());
                                ncAssemblyPreSchedulingPlan.setAssemblyName(techDetails.getLineItemName());
                            }
                            ncAssemblyPreSchedulingPlanMapper.insertNcAssemblyPreSchedulingPlan(ncAssemblyPreSchedulingPlan);
                        }
                    }else{
                        String ppn = NewNumber.createNewNumber(ncProcessingPreSchedulingPlanMapper.getPcMainCode(DateUtils.getDate()));
                        int index = ppn.length() - 3;
                        String newStr = ppn.substring(0, index) + "4" + ppn.substring(index + 1);
                        for(NcTechDetail techDetail : v){
                            NcProcessingPreSchedulingPlan ncProcessingPreSchedulingPlan = new NcProcessingPreSchedulingPlan();
                            BeanUtils.copyProperties(ncProductPreSchedulingPlanMain,ncProcessingPreSchedulingPlan);
                            ncProcessingPreSchedulingPlan.setProductNumber(techDetail.getCpbm());
                            ncProcessingPreSchedulingPlan.setProductName(techDetail.getProductName());
                            ncProcessingPreSchedulingPlan.setPreProductionNumber("YP"+ newStr);
                            ncProcessingPreSchedulingPlan.setGwCode(techDetail.getGwCode());
                            ncProcessingPreSchedulingPlan.setGwName(techDetail.getGwName());
                            ncProcessingPreSchedulingPlan.setGwItemCode(techDetail.getItemCode());
                            ncProcessingPreSchedulingPlan.setGwItemName(techDetail.getItemName());
                            ncProcessingPreSchedulingPlan.setUnit(techDetail.getUnit());
                            ncProcessingPreSchedulingPlan.setDtyl(techDetail.getDtyl());
                            ncProcessingPreSchedulingPlan.setDdyl(Double.parseDouble(techDetail.getDtyl())*ncProductPreSchedulingPlanMain.getOrderNum()+"");
                            ncProcessingPreSchedulingPlan.setCreateBy(SecurityUtils.getUsername());
                            ncProcessingPreSchedulingPlan.setCreateTime(new Date());
                            ncProcessingPreSchedulingPlan.setGxProCode(techDetail.getLineItemCode());
                            ncProcessingPreSchedulingPlan.setItemName(techDetail.getLineItemName());
                            NcTechDetail techDetails = selectItem(techDetail.getLineItemCode(), techDetail.getCpbm());
                            if(StringUtils.isNotNull(techDetails)){
                                ncProcessingPreSchedulingPlan.setPartNumber(techDetails.getLineItemCode());
                                ncProcessingPreSchedulingPlan.setPartName(techDetails.getLineItemName());

                                NcTechDetail tech = selectItem(techDetails.getLineItemCode(), techDetail.getCpbm());
                                ncProcessingPreSchedulingPlan.setZcCode(tech.getLineItemCode());
                                ncProcessingPreSchedulingPlan.setZcName(tech.getLineItemName());
                            }
                            ncProcessingPreSchedulingPlanMapper.insertNcProcessingPreSchedulingPlan(ncProcessingPreSchedulingPlan);
                        }
                    }
                });
            }
            NcProductPreSchedulingPlanMain param = new NcProductPreSchedulingPlanMain();
            param.setIsAudit("1");
            param.setId(id);
            ncProductPreSchedulingPlanMainMapper.updateNcProductPreSchedulingPlanMain(param);
        }
        return 1;

    }

    /*
    * 寻找上级
    * */
    public NcTechDetail selectItem(String lineItemCode,String cpbm){
        NcTechDetail detail = new NcTechDetail();
        detail.setItemCode(lineItemCode);
        detail.setCpbm(cpbm);
        List<NcTechDetail> techDetails = ncTechDetailMapper.selectNcTechDetailList(detail);
        if(techDetails.size()==0){
         return  null;
        }
        return techDetails.get(0);
    }
}
